// Uniform Resource Locator (URL) representation
// Copyright 2004 (C) Ralph Thomas

#ifndef URL_H
#define URL_H

#include <util/string.h>

namespace model {
	//
	/// The url class is used to represent URLs in the mission code. It's
	/// a very simple container with a little parser built in for performing
	/// common actions.
	///
	/// URIs are covered in RFC2396, and are normally in the form of
	/// protocol://user:password\@host/extra/information.
	///
	/// See the RFC for more information:
	///  http://www.ietf.org/rfc/rfc2396.txt
	///
	/// URLs are covered in RFC1736, which can be found here:
	///  http://www.ietf.org/rfc/rfc1736.txt
	//
	class url {
	  public:
		//
		// url* fromString( util::string theUrl )
		//
		/// Return a new URL object created from a string, assuming that
		/// the specified string is actually a valid URL.
		///
		/// \param	theUrl	the URL which the new "url" object
		///			should represent.
		/// \return	a new URL object, or NULL if theUrl is invalid.
		//
		static url* fromString( util::string theUrl );
		//
		// url* fromUri( const url* theUrl )
		//
		/// Return a new URL object, which is a copy of the given one.
		///
		/// \param	theUrl	the url object to copy from.
		/// \return	a new URL object, or NULL if theUrl is NULL.
		//
		static url* fromUrl( const url* theUri );
		//
		// ~url()
		//
		/// Virtual destructor.
		//
		virtual ~url();
		//
		// util::string getCompleteUrl()
		//
		/// Return the complete URL as a string in the format described
		/// by RFC2396.
		///
		/// \return	this URI in string form.
		//
		virtual util::string getCompleteUrl() const = 0;
		//
		// util::string getPrintableUrl()
		//
		/// Return the URI like getCompleteUrl would return, only
		/// don't put any passwords into it.
		///
		/// \return	this URI in a string form without passwords.
		//
		virtual util::string getPrintableUrl() const = 0;
		//
		// util::string getUrlWithoutParts( unsigned int parts ) const
		//
		/// Return the URL without the parts specified. The parts
		/// parameter can be any of the following parts OR'd together:
		///  - kUsername
		///  - kPassword
		///  - kHostname (although this might break the URL)
		///  - kPort
		///  - kPath
		///  - kQuery
		///
		/// All URLs returned by this method have the protocol present.
		///
		/// \return	the URL without the specified parts.
		//
		virtual util::string getUrlWithoutParts( unsigned int parts ) const = 0;
		//
		// util::string getProtocol()
		//
		/// Return the protocol name for this URI. If no protocol was
		/// specified in the source URI, then it is implicitly set to
		/// "file".
		///
		/// \return	the protocol name as a string.
		//
		virtual util::string getProtocol() const = 0;
		//
		// util::string getUsername()
		//
		/// Return the username in this URI. If the URI has no username
		/// embedded in it then return the empty string.
		///
		/// \return	the URI's username, or the empty string.
		//
		virtual util::string getUsername() const = 0;
		//
		// util::string getPassword()
		//
		/// Return the password in this URI. If the URI has no password
		/// embedded in it, then return the empty string.
		///
		/// \return	the URI's password, or the empty string.
		//
		virtual util::string getPassword() const = 0;
		//
		// util::string getHostname()
		//
		/// Return the hostname specified in this URI. If no hostname is
		/// specified then "localhost" is returned.
		///
		/// \return	the URI's hostname, or "localhost".
		//
		virtual util::string getHostname() const = 0;
		//
		// int getPort()
		//
		/// Return the TCP/IP port that the URI specifies, or -1 if
		/// one was not specified in the URI.
		///
		/// \return	the TCP/IP port, or -1.
		//
		virtual int getPort() const = 0;
		//
		// util::string getPath()
		//
		/// Return the path or resource specifier of the URI. If this
		/// isn't present, then "/" is returned.
		///
		/// \return	the URI's path, or "/".
		//
		virtual util::string getPath() const = 0;
		//
		// void setPath( util::string path )
		//
		/// Set the path of this URL to the given one. To stop this URL
		/// from using a path, pass an empty string.
		///
		/// \param	path	the new path for this URL to use.
		//
		virtual void setPath( util::string path ) = 0;
		//
		// unsigned int getNumberArguments() const
		//
		/// Return the number of key/value argument pairs in the "query"
		/// section of the URL.
		///
		/// \return	the number of key/value arguments
		//
		virtual unsigned int getNumberArguments() const = 0;
		//
		// util::string getArgumentKey( unsigned int i ) const
		//
		/// Return the key of a key/value pair at the given index. If
		/// there aren't as many as "i" keys, then an empty string is
		/// returned instead.
		///
		/// \return	the i-th key, or an empty string.
		//
		virtual util::string getArgumentKey( unsigned int i ) const = 0;
		//
		// util::string getArgumentValue( unsigned int i ) const
		//
		/// Return the value of a key/value pair at the given index. If
		/// there aren't as many as "i" key/value pairs then the empty
		/// string is returned.
		///
		/// \param	i	the index of the value to return.
		/// \return	the value associated with the i-th key, or the
		///		empty string.
		//
		virtual util::string getArgumentValue( unsigned int i ) const = 0;
		//
		// util::string getArgumentValue( util::string key ) const
		//
		/// Return the value associated with the specified key.
		///
		/// \param	key	the key which the value is associated with.
		/// \return	the value, or an empty string if the given key is
		///		not found.
		//
		virtual util::string getArgumentValue( util::string key ) const = 0;
		//
		// enum ePresentParts
		//
		/// The presentParts enum has some values which get OR'd
		/// together to generate the return value of getPresentParts().
		///
		/// \sa	getPresentParts
		//
		enum ePresentParts {
			kProtocol = 1,	///< A protocol name is in the URL
			kUsername = 2,	///< A username is in the URL
			kPassword = 4,	///< A password is in the URL
			kHostname = 8,	///< A hostname is in the URL
			kPort = 16,	///< A port number is in the URL
			kPath = 32,	///< A location path is in the URL
			kQuery = 64	///< A query (? section) is in the URL
		};
		//
		// int getPresentParts()
		//
		/// Returns an integer value describing the present parts in the
		/// URL. The integer value is all of the present parts' names
		/// from the ePresentParts enum OR'd together.
		///
		/// \return	an integer value corresponding to the parts
		///		present in this URL.
		//
		virtual int getPresentParts() const = 0;
		//
		// bool equals( const url* otherUrl ) const
		//
		/// If this url is equal to the given URL then true is returned.
		/// If this URL is not equal to the given URL, then false is
		/// returned.
		///
		/// \param	otherUrl	the URL to check equality with
		/// \return	true		this URL is equal to the given
		///				URL.
		///		false		this URL is not equal to the
		///				given URL.
		//
		virtual bool equals( const url* otherUrl ) const = 0;
	};
};

#endif

